package com.steel.yfmall.cloud.assistant.view.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.steel.yfmall.cloud.assistant.goods.ProductLibProductFromService;
import com.steel.yfmall.cloud.assistant.view.GoodsTemplateService;
import com.steel.yfmall.cloud.assistant.zg.ZgSOService;
import com.steel.yfmall.cloud.assistant.dto.para.view.ParaGoodsTemplateBean;
import com.steel.yfmall.cloud.assistant.dto.zg.SynZgResult;
import com.steel.yfmall.cloud.assistant.dto.zg.ZgSOResultBean;
import com.steel.yfmall.cloud.assistant.dto.zg.ZgViewBean;
import com.steel.yfmall.cloud.assistant.dto.zg.result.ZgGoodsTemplateBean;
import com.steel.yfmall.cloud.assistant.po.goods.ProductLibProductFrom;
import com.steel.yfmall.cloud.assistant.po.view.GoodsTemplateBean;
import com.steel.yfmall.cloud.assistant.po.view.GoodsTemplateBeanExample;
import com.steel.yfmall.cloud.assistant.utils.zg.ZgViewUtil;
import com.steel.yfmall.cloud.assistant.view.mapper.GoodsTemplateBeanMapper;
import com.steel.yfmall.cloud.components.mq.bean.RequestSendMQBean;
import com.steel.yfmall.cloud.components.mq.service.MqSendService;
import com.steel.yfmall.cloud.components.utils.base.APIMsgBean;
import com.steel.yfmall.cloud.components.utils.base.ResponseCode;
import com.steel.yfmall.cloud.components.utils.base.SOAStateBean;
import com.steel.yfmall.cloud.components.utils.utils.MobileBaseBeanUtils;
import com.steel.yfmall.cloud.components.utils.utils.UtilDate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author yuchaohua
 * @version V1.0
 * @Title: GoodsTemplateServiceImpl
 * @Package com.work.shop.cloud.service.impl
 * @Description: (用一句话描述该文件做什么)
 * @date 2020/11/18 15:19
 */
@Service
@Slf4j
public class GoodsTemplateServiceImpl implements GoodsTemplateService {

    /**
     * 同步商品服务
     */
    @Resource
    private GoodsTemplateBeanMapper goodsTemplateBeanMapper;

    @Resource
    private ZgSOService zgSOService;

    @Resource
    private ProductLibProductFromService productLibProductFromService;

    @Resource
    private MqSendService mqSendService;

    /**
     * 根据电商已有产品形态进行商品同步
     * @Title: SyncGoodsTemplateBeanByLibFrom
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param  参数说明
     * @return com.steel.yfmall.cloud.components.utils.base.APIMsgBean<java.lang.Integer>    返回类型
     * @author yuchaohua
     * @date 2020/11/18 22:09
     */
    @Override
    public APIMsgBean<Integer> SyncGoodsTemplateBeanByLibFrom() {
        APIMsgBean<Integer> integerAPIMsgBean = new APIMsgBean<>();
        int batchNum = 0;
        ProductLibProductFrom productLibProductFrom = new ProductLibProductFrom();
        List<ProductLibProductFrom> productLibProductFroms = productLibProductFromService.getList(productLibProductFrom);
        if (CollectionUtils.isNotEmpty(productLibProductFroms)) {
            // 根据不同形态进行商品数据同步
            for (ProductLibProductFrom item : productLibProductFroms) {
                ParaGoodsTemplateBean templateBean = new ParaGoodsTemplateBean();
                templateBean.setProdTypeNo(item.getProductFormCode());
                ZgViewBean zgViewBean = new ZgViewBean();
                zgViewBean.setPageNum("1");
                zgViewBean.setParam(templateBean);
                zgViewBean.setMethod(ZgViewUtil.GET_VIEW_NAME);
                zgViewBean.setViewId(ZgViewUtil.IX_01_NEW_VIEW);
                APIMsgBean<SynZgResult> synZgResultAPIMsgBean = synchronizationGoodsTemplateBeanBean(zgViewBean);
                // 记录总同步条数
                if (synZgResultAPIMsgBean != null && null != synZgResultAPIMsgBean.getData()){
                    batchNum += synZgResultAPIMsgBean.getData().getCountNum().intValue();
                }
            }
        }
        integerAPIMsgBean.setData(batchNum);
        return integerAPIMsgBean;
    }

    /**
     * 同步数据
     *
     * @param zgViewBean
     * @return
     */
    public APIMsgBean<SynZgResult> synchronizationGoodsTemplateBeanBean(ZgViewBean zgViewBean) {
        APIMsgBean<SynZgResult> apiMsgBean = new APIMsgBean<>();
        Map<String, String> params = new HashMap<>();
        params.put("method", "方法");
        params.put("viewId", "视图");
        params.put("pageNum", "页码");
        SOAStateBean soaStateBean = ResponseCode.checkApiParameter(params, zgViewBean);
        if (soaStateBean == null || StringUtils.isNotBlank(soaStateBean.getMessage())) {
            apiMsgBean.setSoaStateBean(soaStateBean);
            return apiMsgBean;
        }
        int syncNum = 0;
        SynZgResult synZgResult = new SynZgResult();
        //同步计时开始
        long beginTime = System.currentTimeMillis();
        //查询tp01商品无主库存信息请求中冠
        ZgSOResultBean viewData = zgSOService.getViewData(zgViewBean);
        //同步计时结束
        long endTime = System.currentTimeMillis();
        long costTime = (endTime - beginTime);
        //请求中冠成功后
        if ("Y".equals(viewData.getIsSuccess())) {
            List<ZgGoodsTemplateBean> zgTemplateBeanList = null;
            try {
                zgTemplateBeanList = JSONObject.parseArray(viewData.getData(), ZgGoodsTemplateBean.class);
                if (!CollectionUtils.isEmpty(zgTemplateBeanList)) {
                    //检查数据库是否有重复,过滤掉重复信息并设置创建、更新、版本信息
                    APIMsgBean<Integer> integerAPIMsgBean = checkDataBaseAndBatch(zgTemplateBeanList);
                    //批量新增
                    if (null != integerAPIMsgBean && integerAPIMsgBean.getData().intValue() > 0) {
                        syncNum += integerAPIMsgBean.getData();
                        //设置同步条数
                        synZgResult.setCountNum(integerAPIMsgBean.getData());
                        apiMsgBean.setData(synZgResult);
                    }
                } else {
                    apiMsgBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("无数据同步"));
                }
            } catch (Exception e) {
                log.error("商品无主库存信息数据同步解析出错，错误信息：" , e);
            }
        }
        //递归同步
        try {
            //起始页
            int startPage = Integer.parseInt(zgViewBean.getPageNum());
            //判断是否还有数据
            if (null != viewData && viewData.getZgpageData() != null && startPage < viewData.getZgpageData().getPages()) {
                startPage++;
                zgViewBean.setPageNum(String.valueOf(startPage));
                APIMsgBean<SynZgResult> synZgResultAPIMsgBean = synchronizationGoodsTemplateBeanBean(zgViewBean);
                if (synZgResultAPIMsgBean != null && synZgResultAPIMsgBean.getData() != null){
                    // 记录总同步条数
                    if (synZgResultAPIMsgBean != null && null != synZgResultAPIMsgBean.getData()){
                        syncNum += synZgResultAPIMsgBean.getData().getCountNum().intValue();
                    }
                }
            }
        } catch (Exception e) {
            log.error("商品无主库存信息数据递归同步出错，错误信息：" , e);
        }
        synZgResult.setCountNum(syncNum);
        apiMsgBean.setData(synZgResult);
        return apiMsgBean;
    }

    /**
     * 商品同步与校验
     * @Title: checkDataBaseAndBatch
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param zgTemplateBeanList 参数说明
     * @return com.steel.yfmall.cloud.components.utils.base.APIMsgBean<java.lang.Integer>    返回类型
     * @author yuchaohua
     * @date 2020/11/18 21:48
     */
    @Override
    public APIMsgBean<Integer> checkDataBaseAndBatch(List<ZgGoodsTemplateBean> zgTemplateBeanList) {
        APIMsgBean<Integer> integerAPIMsgBean = new APIMsgBean<>();
        integerAPIMsgBean.setData(0);
        // 检测是否有同步的商品
        if (CollectionUtils.isEmpty(zgTemplateBeanList)) {
            integerAPIMsgBean.setSoaStateBean(ResponseCode.buildEnumSuccessSOAStateBean("暂无需要同步的数据!"));
            return integerAPIMsgBean;
        }
        // 商品编码集合
        Set<String> attrEncryptionList = new HashSet<>();
        // 需要修改的商品
        Set<String> resultUpdateGoods = new HashSet<String>();
        Map<String, ZgGoodsTemplateBean> zgGoodsTemplateBeanMap = new HashMap<>();
        // 对商品进行处理
        for (ZgGoodsTemplateBean itemBean : zgTemplateBeanList) {
            //md5加密商品
            String attrEncryption = goodsIndexMd5(itemBean);
            if (StringUtils.isNotBlank(attrEncryption)) {
                itemBean.setAttrEncryption(attrEncryption);
                attrEncryptionList.add(attrEncryption);
                zgGoodsTemplateBeanMap.put(attrEncryption, itemBean);
            }
        }
        ParaGoodsTemplateBean paraGoodsTemplateBean = new ParaGoodsTemplateBean();
        paraGoodsTemplateBean.setAttrEncryptionList(new ArrayList<>(attrEncryptionList));
        // 获取数据库中对应的商品
        Map<String, GoodsTemplateBean> resultTemplateBeanMap = getGoodsTemplateBeanMapByPara(paraGoodsTemplateBean);
        if (null != resultTemplateBeanMap && resultTemplateBeanMap.size() > 0) {
            for(Map.Entry<String, GoodsTemplateBean> dbGoods : resultTemplateBeanMap.entrySet()){
                String key = dbGoods.getKey();
                resultUpdateGoods.add(key);
                // 剩下的是要新增的商品
              attrEncryptionList.remove(key);
            }
        }

        String msg = "";
        int goodsInt = 0;
        // 需要新增的商品
        if (CollectionUtils.isNotEmpty(attrEncryptionList)) {
            List<GoodsTemplateBean> addBeanList = new ArrayList<>();
            for (String goods : attrEncryptionList) {
                GoodsTemplateBean goodsTemplateBean = new GoodsTemplateBean();
                MobileBaseBeanUtils.copyAllFields(zgGoodsTemplateBeanMap.get(goods), goodsTemplateBean);
                goodsTemplateBean.setAttrEncryption(goods);
                // 版本+1
                goodsTemplateBean.setVersionInt(1);
                goodsTemplateBean.setCreateTime(UtilDate.getDate());
                addBeanList.add(goodsTemplateBean);
            }
            goodsInt += addBeanList.size();
            batchInsertGoodsTemplateBean(addBeanList);
            msg += " 新增：" + addBeanList.size() + " 条";

            //循环下发mq，同步数据到商品表
            for (GoodsTemplateBean goodsTemplateBean : addBeanList) {
                RequestSendMQBean requestSendMQBean = new RequestSendMQBean();
                requestSendMQBean.setSendMqTitle("produc_sync_listener");
                requestSendMQBean.setSendMqMessage(JSON.toJSONString(goodsTemplateBean));
                mqSendService.sendCommonMQMessage(requestSendMQBean);
            }
        }
        integerAPIMsgBean.setData(goodsInt);
        integerAPIMsgBean.setSoaStateBean(ResponseCode.buildEnumSuccessSOAStateBean(msg));
        return integerAPIMsgBean;
    }

    /***
     * 线程修改数据
     */
    private class AsynchronousUpDate implements Runnable {
        List<GoodsTemplateBean> templateBeans;

        public AsynchronousUpDate(List<GoodsTemplateBean> receivingGoodsBeans) {
            this.templateBeans = receivingGoodsBeans;
        }

        @Override
        public void run() {
            try {
                if (!CollectionUtils.isEmpty(templateBeans)) {
                    //记录总需改数据
                    int i = 0;
                    long begintime = System.currentTimeMillis();
                    for (GoodsTemplateBean itemBean : templateBeans) {
                        ParaGoodsTemplateBean paraBean = new ParaGoodsTemplateBean();
                        paraBean.setAttrEncryption(itemBean.getAttrEncryption());
                        updateGoodsTemplateBean(paraBean, itemBean);
                        i++;
                    }
                    long endtime = System.currentTimeMillis();
                    long costTime = (endtime - begintime);
                    log.info("异步修改无主库存信息成功，本次修改" + i + "条数据，耗时" + costTime + "毫秒");
                }
            } catch (Exception e) {
                log.error("同步后的差异数据修改失败，错误原因：" , e);
            }
        }
    }


    /**
     * 商品唯一编码加密
     *
     * @return java.lang.String    返回类型
     * @Title: goodsIndexMd5
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param paraBean 参数说明
     * @author yuchaohua
     * @date 2020/11/18 19:40
     */
    public String goodsIndexMd5(ZgGoodsTemplateBean paraBean) {
        if (null == paraBean) {
            return null;
        }

        ZgGoodsTemplateBean templateBean = new ZgGoodsTemplateBean();
        if (ZgViewUtil.H.equals(paraBean.getProdClass())) {
            templateBean.setBrandId(paraBean.getBrandId());
            templateBean.setProdClass(paraBean.getProdClass());
            templateBean.setProdTypeNo(paraBean.getProdTypeNo());
            templateBean.setTradeNo(paraBean.getTradeNo());
            templateBean.setStockId(paraBean.getStockId());
            templateBean.setProdThick(new BigDecimal(paraBean.getProdThick().stripTrailingZeros().toPlainString()));
            templateBean.setProdWidth(new BigDecimal(paraBean.getProdWidth().stripTrailingZeros().toPlainString()));
            templateBean.setProdLen(new BigDecimal(paraBean.getProdLen().stripTrailingZeros().toPlainString()));
            templateBean.setSizeMsg(paraBean.getSizeMsg());
            templateBean.setGrade(paraBean.getGrade());
            templateBean.setCountWgtMode(paraBean.getCountWgtMode());
            templateBean.setSizePieces(paraBean.getSizePieces());
            templateBean.setCraft(paraBean.getCraft());
            templateBean.setIsDowngrade(paraBean.getIsDowngrade());
            templateBean.setColor(paraBean.getColor());
            templateBean.setTransWayNo(paraBean.getTransWayNo());
        } else {
            templateBean.setBrandId(paraBean.getBrandId());
            templateBean.setProdClass(paraBean.getProdClass());
            templateBean.setProdTypeNo(paraBean.getProdTypeNo());
            templateBean.setStockId(paraBean.getStockId());
            templateBean.setTransWayNo(paraBean.getTransWayNo());
        }
        Map<String, Serializable> params = JSONObject.parseObject(JSONObject.toJSONString(templateBean), HashMap.class);
        if (params == null || params.isEmpty()) {
            return null;
        }

        Set<String> keySet = params.keySet();
        String[] a_keys = new String[keySet.size()];
        a_keys = keySet.toArray(a_keys);
        List<String> sortKeys = Arrays.asList(a_keys);
        StringBuffer sb = new StringBuffer();
        for (String sortKey : sortKeys) {
            sb.append(sortKey).append("=").append(params.get(sortKey)).append("&");
        }
        if (sb != null && sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return DigestUtils.md5Hex(sb.toString());
    }

    /**
     * 获取中冠商品信息集合
     *
     * @return java.util.List<com.steel.yfmall.cloud.assistant.po.view.GoodsTemplateBean>    返回类型
     * @Title: getGoodsTemplateBeans
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param paraBean 参数说明
     * @author yuchaohua
     * @date 2020/11/18 16:03
     */
    public List<GoodsTemplateBean> getGoodsTemplateBeans(ParaGoodsTemplateBean paraBean) {
        List<GoodsTemplateBean> returnListBean = null;
        GoodsTemplateBeanExample example = new GoodsTemplateBeanExample();
        GoodsTemplateBeanExample.Criteria criteria = example.createCriteria();
        getSearchData(paraBean, criteria);
        if (criteria.getCriteria().size() <= 0) {
            return null;
        }
        returnListBean = goodsTemplateBeanMapper.selectByExample(example);
        return returnListBean;
    }

    /**
     * 获取中冠商品信息集合(Map)
     *
     * @return java.util.Map<java.lang.String, com.steel.yfmall.cloud.assistant.po.view.GoodsTemplateBean>    返回类型
     * @Title: getGoodsTemplateBeanListByPara
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param paraBean 参数说明
     * @author yuchaohua
     * @date 2020/11/18 16:03
     */
    public Map<String, GoodsTemplateBean> getGoodsTemplateBeanMapByPara(ParaGoodsTemplateBean paraBean) {
        Map<String, GoodsTemplateBean> returnMapBean = null;
        // 活动信息不能为空
        if (paraBean == null || CollectionUtils.isEmpty(paraBean.getAttrEncryptionList())) {
            return null;
        }
        List<GoodsTemplateBean> resultPrizeSendBeans = getGoodsTemplateBeans(paraBean);
        if (CollectionUtils.isNotEmpty(resultPrizeSendBeans)) {
            returnMapBean = new HashMap<>();
            for (GoodsTemplateBean itemBean : resultPrizeSendBeans) {
                if (StringUtils.isNotBlank(itemBean.getAttrEncryption())) {
                    returnMapBean.put(itemBean.getAttrEncryption(), itemBean);
                }
            }
        }
        return returnMapBean;
    }

    /**
     * 更新商品信息
     *
     * @return boolean    返回类型
     * @Title: updateGoodsTemplateBean
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param paraBean 参数说明
     * @Param recordBean 参数说明
     * @author yuchaohua
     * @date 2020/11/18 16:04
     */
    public boolean updateGoodsTemplateBean(ParaGoodsTemplateBean paraBean, GoodsTemplateBean recordBean) {
        if (paraBean == null || recordBean == null) {
            return false;
        }
        GoodsTemplateBeanExample example = new GoodsTemplateBeanExample();
        GoodsTemplateBeanExample.Criteria criteria = example.createCriteria();
        getSearchData(paraBean, criteria);
        if (criteria.getCriteria().size() <= 0) {
            return false;
        }
        recordBean.setUpdateTime(UtilDate.getDate());
        return goodsTemplateBeanMapper.updateByExampleSelective(recordBean, example) > 0;
    }

    /**
     * 批量新增商品信息
     *
     * @return boolean    返回类型
     * @Title: batchInsertGoodsTemplateBean
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param recordListBean 参数说明
     * @author yuchaohua
     * @date 2020/11/18 16:04
     */
    public int batchInsertGoodsTemplateBean(List<GoodsTemplateBean> recordListBean) {
        int insertInt = 0;
        if (CollectionUtils.isEmpty(recordListBean)) {
            return insertInt;
        }
        return goodsTemplateBeanMapper.batchInsertByList(recordListBean);
    }

    /**
     * 拼接参数
     *
     * @param paraBean
     * @param criteria
     */
    private void getSearchData(ParaGoodsTemplateBean paraBean, GoodsTemplateBeanExample.Criteria criteria) {
        if (paraBean == null || criteria == null) {
            return;
        }
        // 用途码
        if (paraBean.getId() != null && paraBean.getId() > 0) {
            criteria.andIdEqualTo(paraBean.getId());
        }
        // 产品大类
        if (StringUtils.isNotBlank(paraBean.getProdClass())) {
            criteria.andProdClassEqualTo(paraBean.getProdClass());
        }
        // 产品型态
        if (StringUtils.isNotBlank(paraBean.getProdTypeNo())) {
            criteria.andProdClassEqualTo(paraBean.getProdTypeNo());
        }
        // 商品属性加密成唯一键md5
        if (StringUtils.isNotBlank(paraBean.getAttrEncryption())) {
            criteria.andAttrEncryptionEqualTo(paraBean.getAttrEncryption());
        }
        // 商品属性加密成唯一键md5 集合
        if (CollectionUtils.isNotEmpty(paraBean.getAttrEncryptionList())) {
            criteria.andAttrEncryptionIn(paraBean.getAttrEncryptionList());
        }

    }


}
